This short tutorial is about a simple LED and timer demo for a STC8A8K64S4A12 Development Board. I bought the board on ebay when looking for an STC-based board tha thas enough RAnm to actually run some benchmarks. It turned out surprisingly hard to get one, though: Despite being avaialble form multiple sellers, all of them except for one were unable to receive Payment due to having their Paypal account closed. The one that actually was able to receive Payment only sold it in quantities of 5. Soon after, all offers of this board disappeared from ebay.
The author used a Debian GNU/Linux system, but the tutorial should work for other Linux distributions, *BSD or other Unices.
The tools we use are
To supply power and to write the program the board is connected via Mini-USB.
Depending on your operating system there might be an easy way to install SDCC 3.5.0 or newer using a package system or similar (e.g. apt-get install sdcc on Debian). While SDCC 3.4.0 should be sufficient for this tutorial, you might want to try a newer version in case you encounter any bugs.
SDCC binaries or a source tarball can be downloaded from its website.
ec2writeflash is part of the ec2-new package.
The ec2-new source can be found at its GitHub location, where there is also a download link for a zip archive of the sources. To compile it, a C compiler, such as gcc, autotools and some necessary libraries need to be installed. Unzip the archive (e.g. using unzip stm8flash-master.zip) change into the directory stm8flash-master and type autoreconf; automake --add-missing; libtoolize; autoreconf; ./configure && make
. In case there are any errors, such as header files not found, check that all necessary libraries are installed.
We present a simple Demo that increments a 4-bit LED counter once per second. This demonstrates setting up and using an accurate timer and doing basic I/O. Here is the C code:
// Source code under CC0 1.0 #include <stdbool.h> #include <stdint.h> __sfr __at(0xb0) P3; __sfr __at(0x88) TCON; __sfr __at(0x89) TMOD; __sfr __at(0x8a) TL0; __sfr __at(0x8c) TH0; __sfr __at(0xa8) IE; __sfr __at(0xba) P_SW2; #define CLKDIV (*(__xdata uint8_t *)(0xfe01)) volatile unsigned long int clocktime; volatile bool clockupdate; void clockinc(void) __interrupt(1) { TH0 = (65536 - 2000) / 256; TL0 = (65536 - 2000) % 256; clocktime++; clockupdate = true; } unsigned long int clock(void) { unsigned long int ctmp; do { clockupdate = false; ctmp = clocktime; } while (clockupdate); return(ctmp); } void main(void) { // Set the system clock to 24 Mhz // (experiments show that it actually already is at 24 Mhz at startup, // But the datasheet claims it is at 3 Mhz, as it states the reset value // of CLKDIV as 8. P_SW2 |= 0x80; // Enable access to memory-mapped expanded sfr, such as CLKDIV. CLKDIV = 1; // Configure timer for 24 Mhz main clock // 1000 ticks per second TH0 = (65536 - 2000) / 256; TL0 = (65536 - 2000) % 256; TMOD = 0x01; IE |= 0x82; TCON |= 0x10; // Start timer for(unsigned long i = 0;; i++) P3 = ~(clock() / 1000) & 0x0f; }
SDCC is a freestanding, not a hosted implemenatation of C, and allows main to return void.
We set up the timer to generate an interupt once per millisecond, which allows us to implement a basic clock()
function. This function is used to control the blinking of the LEDs.
The demo can be compiled simply by invocing sdcc using sdcc -mmcs51 --std-c99 led.c
assuming the C code is in led.c. The option -mmcs51
selects the target port (mcs51). An .ihx file with a name corresponding to the source file will be generated.
Via the CH340G on the board, stcgal.py serial.ihx
will write the demo onto the board (if other serial devices are attached via USB, you might ned to specify the port used manually via the -p option). You need to power-cycle the board after invoking stcgal (using SW 1 newxt to the USB connector). Since the LEDs are connected to the serialdata lines which are used to transfer the program onto the µC, they will flicker for a while. After that the demo will run and count up to 15 on the green LEDs, then start again at 0.
stcgal is an STC MCU ISP flash tool for programming STC 8051 compatible microcontrollers written by Grigori Goronzy. STC microcontrollers have an UART / USB based boot strap loader (BSL), that stcgal communicates with. The port used can be specified using -p (e.g. stcgal -p /dev/ttyUSB2 test.ihx to write test.ihx onto the board attahced via the third USB serial port).
SDCC was initially written by Sandeep Dutta for the MCS-51, and has a relatively conservative architecture (see Sandeep Dutta, "Anatomy of a Compiler", 2000). It has been extended by various contributors and more recently, incorporated some cutting-edge technologies, in particular in register allocation (see Philipp Klaus Krause, "Optimal Register Allocation in Polynomial Time", 2013 and "Bytewise Register Allocation", 2015). However the mcs51 backend does not have all the fancy features and optimizations that some newer backends have.
SDCC is a C compiler that aims to be compliant with the C standards.
Important compiler options for MCS-51 developers include:
-c
to compile into object files to be linked later--std-c99
for compilation in C99 mode (some C99 features, e.g. variable-length arrays are not yet supported in sdcc though)--model-large
to use the xram for variables by default